﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;
using DataTreeLib;
using LiveSequence.Common.Domain;
using LiveSequence.Common.Tree;
using LiveSequence.Dialogs;
using LiveSequence.Suite.Controllers;
using LiveSequence.Suite.Documents;
using LiveSequence.Suite.Helpers;
using LiveSequence.Suite.Interfaces;
using LiveSequence.Suite.Interfaces;
using LiveSequence.Suite.Utils;
using LiveSequence.Common.Engine;
using LiveSequence.Suite.Dialogs;
using LiveSequence.Suite.Domain;


namespace LiveSequence.Suite.Views
{
  internal partial class AssemblyExplorerView : BaseView<ProjectDoc>, IAssemblyExplorerView
  {
    private string _assemblyFileName;
    private AssemblyExplorer _assemblyExplorer;
    private TreeViewController<DTreeItem> _tvController;
    private DlgProgressInfo _dlgProcesInfo;
    private DocManager _docManager;
    private CecilAssemblyParserOptions _cecilAssemblyParserOptions;


    public AssemblyExplorerView()
    {
      InitializeComponent();
      InitializeComponentEx();
      _assemblyExplorer = AssemblyExplorer.Instance;
      _assemblyExplorer.Initialize(this);
      SelectedDocument = _docManager.MasterDocument;
      _cecilAssemblyParserOptions = new CecilAssemblyParserOptions();
    }

    private SearchingTreeViewController _searchingTreeViewController;

    private void InitializeComponentEx()
    {
      _docManager = DocManager.Instance;

      _searchingTreeViewController = new SearchingTreeViewController(_treeView, _toolStrip);
      _searchingTreeViewController.SearchText += new EventHandler(_searchingTreeViewController_SearchText);
      _docManager.MasterDocumentChanged += new EventHandler(_docManager_MasterDocumentChanged);
    }

    void _docManager_MasterDocumentChanged(object sender, EventArgs e)
    {
      SelectedDocument = _docManager.MasterDocument;
    }

    void _searchingTreeViewController_SearchText(object sender, EventArgs e)
    {
      string searchedText = _searchingTreeViewController.SearchedText;
      TreeNode tNode = TreeViewHelper.SearchTreeNode(_treeView, new TextTNodeComparer(searchedText));
      if (tNode != null)
      {
        tNode.EnsureVisible();
        _treeView.SelectedNode = tNode;

      }

    }

    private void _btnLoadAssembly_Click(object sender, EventArgs e)
    {
      using (OpenFileDialog assemblyOpenDialog = new OpenFileDialog())
      {

        assemblyOpenDialog.Filter = "Assembly Files (*.exe,*.dll)|*.dll;*.exe|All Files (*.*)|*.*";
        assemblyOpenDialog.InitialDirectory = Application.StartupPath;
        if (DialogResult.OK == assemblyOpenDialog.ShowDialog())
        {
          CleanUp();
          _assemblyExplorer.CleanUp();

          _assemblyFileName = assemblyOpenDialog.FileName;

          // change the form title
          Text = string.Format("SequenceViz :: {0}", _assemblyFileName);

          DlgAssemblyParserOptions dlg = new DlgAssemblyParserOptions(_assemblyFileName);
          if(dlg.ShowDialog() == DialogResult.OK)
          {
            _cecilAssemblyParserOptions = dlg.CecilAssemblyParserOptions;
            StartProgress();
          }
        }
      }
    }

    private void StartProgress()
    {
      _assemblyExplorer.RunWorker(_assemblyFileName);
      _dlgProcesInfo = new DlgProgressInfo();
      _dlgProcesInfo.ShowDialog();

      _tvController = new TreeViewController<DTreeItem>(_treeView,
                                                       _assemblyExplorer.AssemblyParser.AssemblyData.AssemblyTree,
                                                       new ImageTreeNodeMapper<DTreeItem, SelectionType>());

      // expand the tree
      _treeView.Nodes[0].Expand();

      _treeView.TreeViewNodeSorter = new NodeSorter();

      _txtAssemblyFileName.Text = Path.GetFileName(_assemblyFileName);

    }

    private void CleanUp()
    {
    }

    #region IMainFormView Members

    public DTreeNode<DTreeItem> AssemblyTree
    {
      get; set;
    }

    public string AssemblyFileName
    {
      get { return _assemblyFileName; }
    }

    public void WorkerCompleted()
    {
      _dlgProcesInfo.Close();
      
    }

    public void WorkerProgressChanged(ProgressChangedEventArgs e)
    {

      _dlgProcesInfo.ProgressChanged(e.ProgressPercentage, e.UserState);
    }

    #endregion

    private void _treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
    {
      DTreeNode<DTreeItem> treeNode = e.Node.Tag as DTreeNode<DTreeItem>;
      if(treeNode!=null)
      {
        if(treeNode.Value.SelectionType == SelectionType.METHOD)
        {
          if (_tvController.SelectedNode.Value.Text.IndexOf('(') > 0)
          {
            string strMethodName = _tvController.SelectedNode.Value.Text;
            string strTypeName = _tvController.SelectedNode.Parent.Value.Text;
            string strNameSpace = _tvController.SelectedNode.Parent.Parent.Value.Text;
            string strAssemblyName = _tvController.SelectedNode.Parent.Parent.Parent.Value.Text;

            SequenceData sequenceData = AssemblyExplorer.Instance.GetSequenceData(strMethodName, strTypeName, strNameSpace, strAssemblyName);            
            LSMethodCallDiagram diagram = new LSMethodCallDiagram(strMethodName, strTypeName, strNameSpace, strAssemblyName, (SequenceData)sequenceData.Clone());
            SeqDiagramDoc seqDiagramDoc = new SeqDiagramDoc(diagram);
            SelectedDocument.AddDiagram(seqDiagramDoc);
          }
        }
      }
   
    }




    #region IAssemblyExplorerView Members


    public CecilAssemblyParserOptions CecilAssemblyParserOptions
    {
      get
      {
        return _cecilAssemblyParserOptions;
      }
    }

    #endregion
  }
}
